package cameragps;

import java.util.Timer;
import java.util.TimerTask;
import java.util.Vector;

import javax.microedition.io.Connector;
import javax.microedition.io.file.FileConnection;
import javax.microedition.media.Manager;
import javax.microedition.media.MediaException;
import javax.microedition.media.Player;
import javax.microedition.media.control.VideoControl;

import net.rim.device.api.applicationcontrol.ApplicationPermissions;
import net.rim.device.api.applicationcontrol.ApplicationPermissionsManager;
import net.rim.device.api.system.Application;
import net.rim.device.api.system.Backlight;
import net.rim.device.api.system.Bitmap;
import net.rim.device.api.system.Characters;
import net.rim.device.api.system.DeviceInfo;
import net.rim.device.api.system.GlobalEventListener;
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.Keypad;
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.MenuItem;
import net.rim.device.api.ui.component.*;
import net.rim.device.api.ui.container.MainScreen;
import net.rim.device.api.ui.container.PopupScreen;
import net.rim.device.api.ui.container.VerticalFieldManager;
import net.rim.device.api.util.StringUtilities;

public final class helloBerry extends UiApplication implements
		GlobalEventListener {

	protected static int dID;

	helloBerryScreen screen;
	static sendUnsentService service;

	public static void main(String[] args) {

		if (args != null && args.length > 0 && args[0].equals("normal")) {
			System.out.println("_________[STARTING APP]");

			ApplicationPermissionsManager apm = ApplicationPermissionsManager
					.getInstance();
			boolean userChoice = true;
			if (apm.getPermission(ApplicationPermissions.PERMISSION_DEVICE_SETTINGS) != ApplicationPermissions.VALUE_ALLOW
					&& apm.getPermission(ApplicationPermissions.PERMISSION_FILE_API) != ApplicationPermissions.VALUE_ALLOW
					&& apm.getPermission(ApplicationPermissions.PERMISSION_INTERNET) != ApplicationPermissions.VALUE_ALLOW
					&& apm.getPermission(ApplicationPermissions.PERMISSION_LOCATION_DATA) != ApplicationPermissions.VALUE_ALLOW
					&& apm.getPermission(ApplicationPermissions.PERMISSION_RECORDING) != ApplicationPermissions.VALUE_ALLOW)

			{
				ApplicationPermissions ap = new ApplicationPermissions();
				ap.addPermission(ApplicationPermissions.PERMISSION_DEVICE_SETTINGS);
				ap.addPermission(ApplicationPermissions.PERMISSION_FILE_API);
				ap.addPermission(ApplicationPermissions.PERMISSION_INTERNET);
				ap.addPermission(ApplicationPermissions.PERMISSION_LOCATION_DATA);
				ap.addPermission(ApplicationPermissions.PERMISSION_RECORDING);
				userChoice = apm.invokePermissionsRequest(ap);
			}

			if (userChoice) {
				Backlight.setTimeout(255);
			} else {
				return;
			}
			helloBerry theApp = new helloBerry();
			theApp.enterEventDispatcher();
		} else {
			System.out.println("_________[STARTING SERVICE]");

			service = new sendUnsentService();
			service.enterEventDispatcher();

		}
	}

	public helloBerry() {

		try {
			dID = DeviceInfo.getDeviceId();

			screen = new helloBerryScreen();
			pushScreen(screen);
		} catch (Exception e) {
			helloBerry.errorDialog("Error starting application!");

		}
	}

	public static void errorDialog(final String message) {
		UiApplication.getUiApplication().invokeLater(new Runnable() {
			public void run() {
				Dialog.alert(message);
			}
		});
	}

	public void eventOccurred(long guid, int data0, int data1, Object object0,
			Object object1) {

	}

}

final class sendUnsentService extends Application {

	Timer timer;
	TimerTask repeatMe;

	public sendUnsentService() {
		ImageUtils.initPersistentStorage();
		timer = new Timer();

		repeatMe = new TimerTask() {

			public void run() {
				sendUnsentActivity();
			}
		};
		timer.schedule(repeatMe, 0, 300000);// 60000
	}

	/**
	 * This method do the activity for uploading unsent pictures
	 */
	static void sendUnsentActivity() {
		for (int i = 0; i < ImageUtils.dataVector.size(); i++) {
			try {
				ImageInformation current = (ImageInformation) ImageUtils.dataVector
						.elementAt(i);

				FileConnection fcon = null;
				try {
					fcon = (FileConnection) Connector.open(ImageUtils.path
							+ current.getField(ImageInformation.IMAGENAME),
							Connector.READ_WRITE);
					if (!fcon.exists())
						throw new Exception();

				} catch (Exception e) {
					ImageUtils.removeInformation(i);
					--i;
					continue;
				}

				if (!current.isSent()) {
					current.showData();

					String[] fields = current.getFields();
					System.out.println("_____sending : "
							+ fields[ImageInformation.IMAGENAME]);
					byte[] raw = ImageUtils
							.getBytesFromImage(fields[ImageInformation.IMAGENAME]);
					if (ImageUtils.SendHttpPost(ImageUtils.xmlBuilder(fields,
							raw))) {
						ImageUtils.markAsSent(i);
					}
				}
			} catch (Exception e) {
				break;
			}
		}
	}
}

final class helloBerryScreen extends MainScreen {

	private VideoControl m_videoControl;
	Field m_videoField;

	private EncodingProperties m_encodings;

	private MenuItem m_myPhotosMenuItem = new MenuItem("My Picture Box", 9, 100) {
		public void run() {
			UiApplication.getUiApplication().pushScreen(new MyPhotosScreen());
		}
	};

	private MenuItem m_AccountMenuItem = new MenuItem("My Email Account", 10,
			100) {
		public void run() {
			UiApplication.getUiApplication().pushModalScreen(
					new EnterEmailScreen(ImageUtils.accountString, false));
		}
	};

	public helloBerryScreen() {
		setTitle("World Bank GPS_Camera ");

		initializeCamera();
		initializeEncodingList();
		addMenuItems();

		if (m_videoField != null) {
			createUI();
		} else {
			add(new RichTextField("Error Connecting to Camera."));
		}

		VerticalFieldManager vfm = new VerticalFieldManager(Field.FIELD_HCENTER);

		LabelField welcomeLableField = new LabelField("Welcome!",
				Field.FIELD_HCENTER);
		welcomeLableField.setMargin(5, 5, 5, 5);
		vfm.add(welcomeLableField);

		BitmapField welcomeBitmapField = new BitmapField(
				Bitmap.getBitmapResource("welcome.png"), Field.FIELD_HCENTER);
		welcomeBitmapField.setMargin(0, 5, 5, 5);
		vfm.add(welcomeBitmapField);

		final PopupScreen splash = new PopupScreen(vfm);

		UiApplication.getUiApplication().invokeLater(new Runnable() {

			public void run() {
				UiApplication.getUiApplication().pushModalScreen(splash);

			}
		});

		ImageUtils.initPersistentStorage();

		Thread locationThread = new Thread() {
			public void run() {
				LocationTracker.getSinglePoint();
			}
		};
		locationThread.start();

		Timer t = new Timer();
		t.schedule(new TimerTask() {

			public void run() {
				UiApplication.getUiApplication().invokeLater(new Runnable() {

					public void run() {
						UiApplication.getUiApplication().popScreen(splash);
					}
				});
			}
		}, 4000);

	}

	String encoding;
	protected boolean result;

	public void takePicture() {
		try {
			if (m_encodings != null) {
				encoding = m_encodings.getFullEncoding();

			}

			if (LocationTracker.m_location == null) {

				final PopupScreen waitScreen = ThreadUtils
						.getWaitPopUp("Updating Location");

				ThreadUtils.runningSequance(new Runnable() {

					public void run() {
						UiApplication.getUiApplication().pushModalScreen(
								waitScreen);
					}
				}, new Runnable() {
					public void run() {
						result = LocationTracker.getSinglePoint();
					}
				}, new Runnable() {
					public void run() {
						UiApplication.getUiApplication().popScreen(waitScreen);
						if (result) {
							try {
								createImageScreen(m_videoControl
										.getSnapshot(encoding));
							} catch (MediaException e) {
								e.printStackTrace();
							}
						}
					}
				});
			} else
				createImageScreen(m_videoControl.getSnapshot(encoding));

		} catch (Exception e) {
			helloBerry.errorDialog("Error taking picture!");
		}
	}

	protected boolean onSavePrompt() {
		return true;
	}

	private void initializeCamera() {
		UiApplication.getUiApplication().invokeAndWait(new Runnable() {

			public void run() {
				try {
					Player playerDevice = Manager
							.createPlayer("capture://video");

					playerDevice.realize();

					m_videoControl = (VideoControl) playerDevice
							.getControl("VideoControl");

					if (m_videoControl != null) {
						m_videoField = (Field) m_videoControl.initDisplayMode(
								VideoControl.USE_GUI_PRIMITIVE,
								"net.rim.device.api.ui.Field");
						m_videoControl.setDisplayFullScreen(true);
						m_videoControl.setVisible(true);
					}

					playerDevice.start();
				} catch (Exception e) {
					helloBerry.errorDialog("Error initializing camera!");
				}
			}
		});

	}

	private void initializeEncodingList() {
		String encodingString = System.getProperty("video.snapshot.encodings");
		String[] properties = StringUtilities.stringToKeywords(encodingString);
		Vector encodingList = new Vector();

		String encoding = "encoding";
		String width = "width";
		String height = "height";
		String quality = "quality";

		EncodingProperties temp = null;

		for (int i = 0; i < properties.length; ++i) {

			if (properties[i].equals(encoding)) {
				if (temp != null && temp.isComplete()) {
					encodingList.addElement(temp);
				}
				temp = new EncodingProperties();
				++i;
				temp.SetFormat(properties[i]);
			} else if (properties[i].equals(width)) {
				++i;
				temp.setWidth(properties[i]);
			} else if (properties[i].equals(height)) {
				++i;
				temp.setHeight(properties[i]);
			} else if (properties[i].equals(quality)) {
				++i;
				temp.setQuality(properties[i]);
			}
		}

		if (temp != null && temp.isComplete()) {
			encodingList.addElement(temp);
		}

		m_encodings = new EncodingProperties();
		m_encodings = (EncodingProperties) encodingList.elementAt(encodingList
				.size() - 1);

	}

	/**
	 * Adds menu items
	 */
	private void addMenuItems() {
		addMenuItem(m_AccountMenuItem);
		addMenuItem(m_myPhotosMenuItem);
	}

	private void createUI() {
		this.add(m_videoField);
	}

	private void createImageScreen(byte[] raw) {
		String emailString = ImageUtils.accountString;
		if (emailString.equals("") || emailString == null)
			UiApplication.getUiApplication().pushModalScreen(
					new EnterEmailScreen(emailString, true));
		emailString = ImageUtils.accountString;
		if (!emailString.equals("") && emailString != null)
			UiApplication.getUiApplication().pushScreen(
					new ImageScreen(raw, LocationTracker.m_Logitude,
							LocationTracker.m_Latitude,
							LocationTracker.m_locationAddress));
	}

	protected boolean invokeAction(int action) {
		boolean handled = super.invokeAction(action);

		if (!handled) {
			switch (action) {
			case ACTION_INVOKE: {
				takePicture();
				return true;
			}
			}
		}

		return handled;
	}

	protected boolean keyChar(char keycode, int status, int time) {
		int code = Keypad.key(keycode);

		if (Keypad.KEY_CONVENIENCE_1 == code) {
			takePicture();
			return true;
		}
		if (keycode == Characters.ESCAPE) {
			Backlight.setTimeout(Backlight.getTimeoutDefault());
			close();
		}
		return super.keyDown(keycode, time);
	}

}